#ifndef _UTILS_H_
#define _UTILS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include "lv_drv_conf.h"
#include <stdint.h>

#define BIT_0 (1 << 0)
#define BIT_1 (1 << 1)
#define BIT_2 (1 << 2)
#define BIT_3 (1 << 3)
#define BIT_4 (1 << 4)
#define BIT_5 (1 << 5)
#define BIT_6 (1 << 6)
#define BIT_7 (1 << 7)
#define BIT_8 (1 << 8)
#define BIT_9 (1 << 9)
#define BIT_10 (1 << 10)
#define BIT_11 (1 << 11)
#define BIT_12 (1 << 12)
#define BIT_13 (1 << 13)
#define BIT_14 (1 << 14)
#define BIT_15 (1 << 15)
#define BIT_16 (1 << 16)
#define BIT_17 (1 << 17)
#define BIT_18 (1 << 18)
#define BIT_19 (1 << 19)
#define BIT_20 (1 << 20)
#define BIT_21 (1 << 21)
#define BIT_22 (1 << 22)
#define BIT_23 (1 << 23)
#define BIT_24 (1 << 24)
#define BIT_25 (1 << 25)
#define BIT_26 (1 << 26)
#define BIT_27 (1 << 27)
#define BIT_28 (1 << 28)
#define BIT_29 (1 << 29)
#define BIT_30 (1 << 30)
#define BIT_31 ((unsigned)1 << 31)
#define BIT(x) (1UL << x)

#if USE_UTILS
void pmu_write(uint32_t offset, uint32_t val);
uint32_t pmu_read(uint32_t offset);
void pmu_write_bits(uint32_t offset, uint32_t value, uint32_t bits, uint32_t shifts);
void pmu_set_bits(uint32_t offset, uint32_t bits);
void pmu_clear_bits(uint32_t offset, uint32_t bits);

#if USE_CRANE_LCD || USE_CRANE_CAMERA

void lcdc_write(uint32_t offset, uint32_t val);
uint32_t lcdc_read(uint32_t offset);
void lcdc_write_bits(uint32_t offset, uint32_t value, uint32_t bits, uint32_t shifts);
void lcdc_set_bits(uint32_t offset, uint32_t bits);
void lcdc_clear_bits(uint32_t offset, uint32_t bits);

void jpu_write(uint32_t offset, uint32_t val);
uint32_t jpu_read(uint32_t offset);
void jpu_write_bits(uint32_t offset, uint32_t value, uint32_t bits, uint32_t shifts);
void jpu_set_bits(uint32_t offset, uint32_t bits);
void jpu_clear_bits(uint32_t offset, uint32_t bits);

#endif /* USE_CRANE_LCD || USE_CRANE_CAMERA */
#endif

typedef uint16_t __be16;
typedef uint32_t __be32;
typedef uint64_t __be64;

#define uswap_16(x) \
    ((((x) & 0xff00) >> 8) | \
     (((x) & 0x00ff) << 8))
#define uswap_32(x) \
    ((((x) & 0xff000000) >> 24) | \
     (((x) & 0x00ff0000) >>  8) | \
     (((x) & 0x0000ff00) <<  8) | \
     (((x) & 0x000000ff) << 24))
#define _uswap_64(x, sfx) \
    ((((x) & 0xff00000000000000 ## sfx) >> 56) | \
     (((x) & 0x00ff000000000000 ## sfx) >> 40) | \
     (((x) & 0x0000ff0000000000 ## sfx) >> 24) | \
     (((x) & 0x000000ff00000000 ## sfx) >>  8) | \
     (((x) & 0x00000000ff000000 ## sfx) <<  8) | \
     (((x) & 0x0000000000ff0000 ## sfx) << 24) | \
     (((x) & 0x000000000000ff00 ## sfx) << 40) | \
     (((x) & 0x00000000000000ff ## sfx) << 56))

#if defined(__GNUC__)
# define uswap_64(x) _uswap_64(x, ull)
#else
# define uswap_64(x) _uswap_64(x, )
#endif

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define cpu_to_le16(x)     (x)
# define cpu_to_le32(x)     (x)
# define cpu_to_le64(x)     (x)
# define le16_to_cpu(x)     (x)
# define le32_to_cpu(x)     (x)
# define le64_to_cpu(x)     (x)
# define cpu_to_be16(x)     uswap_16(x)
# define cpu_to_be32(x)     uswap_32(x)
# define cpu_to_be64(x)     uswap_64(x)
# define be16_to_cpu(x)     uswap_16(x)
# define be32_to_cpu(x)     uswap_32(x)
# define be64_to_cpu(x)     uswap_64(x)
# define be32_to_cpup(x)    uswap_32(*(x))

# define __constant_cpu_to_le16(x) ((uint16_t)(x))
#else
# define cpu_to_le16(x)     uswap_16(x)
# define cpu_to_le32(x)     uswap_32(x)
# define cpu_to_le64(x)     uswap_64(x)
# define le16_to_cpu(x)     uswap_16(x)
# define le32_to_cpu(x)     uswap_32(x)
# define le64_to_cpu(x)     uswap_64(x)
# define cpu_to_be16(x)     (x)
# define cpu_to_be32(x)     (x)
# define cpu_to_be64(x)     (x)
# define be16_to_cpu(x)     (x)
# define be32_to_cpu(x)     (x)
# define be64_to_cpu(x)     (x)

#define __constant_cpu_to_le16(x) uswap_16((x))
#endif

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif

